#pragma once

#include <mutex>
#include "ShmCentralCache.hpp"
#include "LOG_CYC.hpp"


class ShmMemoryPool
{
public:
    // 获取单例实例的方法
    static ShmMemoryPool* GetInstance() {
        // 使用双重检查锁定来确保线程安全
        if (_instance == nullptr) {
            std::lock_guard<std::mutex> lock(_mutex);
            if (_instance == nullptr) {
                _instance = new ShmMemoryPool();
                LOG_CYC(NORMAL, "ShmMemoryPool 实例创建", nullptr);
            }
        }
        return _instance;
    }

    // 分配内存
    void* Allocate(size_t size) {
        void* ptr = nullptr;

        if (size > MAX_BYTES) {
            size_t alignSize = SizeClass::RoundUp(size);  // 对齐大小
            size_t kpage = alignSize >> MY_PAGE_SHIFT;      // 计算页数

            //_pageCache->GetPageMtx().lock();
            Span* span = _pageCache->NewSpan(kpage);
            span->_objSize = alignSize;
            //_pageCache->GetPageMtx().unlock();

            ptr = span->_headPtr;
            ObjFile(ptr) = span->_fileId;
            ObjPos(ptr) = span->_spanPos;
        }
        else {
            ptr = _centralCache->FetchRangeObj(size);
        }
        return ptr;
    }

    // 释放内存
    void Deallocate(int32_t fileId, int32_t pos) {
        ShmServiceNode* shmNode = _shmManger->GetShmNodeByFileId(fileId);
        if (shmNode == nullptr) {
            LOG_CYC(FATAL, "共享内存释放失败, fileId：%d，pos", fileId, pos);
            ShmServiceNode* shmNode = _shmManger->GetShmNodeByFileId(fileId);
            exit(0);
        }
        Span* span = shmNode->_pageMap[pos >> PAGE_SHIFT];

        if (span->_objSize > MAX_BYTES) {
            // 将这个Span交给PageCache合并
            //_pageCache->GetPageMtx().lock();  // Page上锁
            _pageCache->ReleaseSpanToPageCache(span);
            //_pageCache->GetPageMtx().unlock();  // Page解锁
        }
        else {
            _centralCache->ReleaseObjectToSpan(fileId, pos);
        }
    }

private:
    // 私有构造函数
    ShmMemoryPool() {
        _centralCache = ShmCentralCache::GetInstance();
        _pageCache = ShmPageCache::GetInstance();
        _shmManger = ShmServiceManger::GetInstance();
    }

    ~ShmMemoryPool() {}

    // 删除复制构造函数和赋值运算符，防止拷贝和赋值
    ShmMemoryPool(const ShmMemoryPool&) = delete;
    ShmMemoryPool& operator=(const ShmMemoryPool&) = delete;

    // 私有静态成员变量
    static ShmMemoryPool* _instance; // 保存唯一实例的指针
    static std::mutex _mutex;        // 静态互斥量，用于实现线程安全

    // 成员变量
    ShmCentralCache* _centralCache = nullptr;
    ShmPageCache* _pageCache = nullptr;
    ShmServiceManger* _shmManger = nullptr;

};

// 在类外初始化静态成员变量
ShmMemoryPool* ShmMemoryPool::_instance = nullptr;
std::mutex ShmMemoryPool::_mutex;
